package vfs.persist.entity.manage.impl;

import java.sql.Connection;
import vfs.persist.VFSIterator;
import java.util.Iterator;
import vfs.filter.VFSFilter;
import vfs.persist.entity.build.impl.VFSEntityBuilderImpl;
import java.sql.SQLException;
import java.sql.ResultSet;
import vfs.obj.entity.VFSEntity;
import vfs.except.VFSException;
import vfs.persist.entity.manage.VFSEntityManager;
import java.util.Map;

import static vfs.util.VFSPersistUtil.*;

/**
 *
 * @author Matthew Eavenson <durandal@uga.edu>
 */
public class VFSEntityManagerImpl<T extends VFSEntity> implements VFSEntityManager<T>{
    
    private final Connection conn;
    private VFSEntityBuilderImpl<T> builder;
    
    public VFSEntityManagerImpl(Connection conn, VFSEntityBuilderImpl<T> builder){
        this.conn = conn;
        this.builder = builder;
    }
    
    @Override
    public void add(T obj) throws VFSException{
        add(obj, null);
    }

    @Override
    public void add(T obj, Map<String, String> foreignKeys) throws VFSException{
        String query = "INSERT INTO "+builder.TABLE+" ("+builder.getFields(foreignKeys)+") VALUES("+builder.getValues(obj, foreignKeys)+")";
        long key = updateDB(conn, query, true);
        obj.setId(key);
    }

    @Override
    public void update(T obj) throws VFSException{
        StringBuilder query = new StringBuilder("UPDATE "+builder.TABLE+" SET ");
        String values = builder.getValues(obj, null);
        String[] fieldArr = builder.getFields();
        String[] valArr = values.split(", ");
        for(int i=0; i<valArr.length; i++){
            query.append(fieldArr[i]+" = "+valArr[i]+", ");
        }
        query.delete(query.length()-2, query.length());
        query.append(" WHERE "+builder.KEY+" = "+obj.getId());
        updateDB(conn, query.toString());
    }

    @Override
    public T get(long id) throws VFSException{
        String query = "SELECT "+builder.KEY+", "+builder.FIELDS+" FROM "+builder.TABLE+" WHERE "+builder.KEY+" = "+id;
        ResultSet rs = queryDB(conn, query);
        try{
            if(rs.next()) return builder.build(rs);
        }catch(SQLException sqe){
            throw new VFSException(sqe.getMessage());
        }
        return null;
    }
    
    @Override
    public Iterator<T> get(VFSFilter filter) throws VFSException{
        filter.setPrefix(" WHERE ");
        String query = "SELECT "+builder.KEY+", "+builder.FIELDS+" FROM "+builder.TABLE+(filter == null?"": filter);
        ResultSet rs = queryDB(conn, query);
        return new VFSIterator<T>(rs, builder);
    }

    @Override
    public void remove(T obj) throws VFSException{
        remove(obj.getId());
    }

    @Override
    public void remove(long id) throws VFSException{
        String query = "DELETE FROM "+builder.TABLE+" WHERE "+builder.KEY+" = "+id;
        updateDB(conn, query);
    }
    
    @Override
    public void remove(VFSFilter filter) throws VFSException{
        if(filter != null){
            String query = "DELETE FROM "+builder.TABLE+" WHERE "+filter;
            updateDB(conn, query);
        }
    }
    
}
